/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufrn.engcomp.mpc.domain;

import br.ufrn.engcomp.mpc.util.MathCommonsUtils;
import br.ufrn.engcomp.mpc.util.OjAlgoUtils;
import org.apache.commons.math.linear.RealMatrix;
import org.apache.commons.math.linear.RealVector;
import org.ojalgo.matrix.store.MatrixStore;
import org.ojalgo.optimisation.OptimisationSolver.Result;
import org.ojalgo.optimisation.State;
import org.ojalgo.optimisation.quadratic.QuadraticSolver;

/**
 *
 * @author Felipe
 */
public class OjAlgoQPSolver implements QPSolver {

    @Override
    public RealVector solve(RealMatrix g, RealVector f, double c, RealMatrix S, RealVector a) {   
        RealVector correctedF = f.mapMultiply(-1);
        
        MatrixStore Q = OjAlgoUtils.convertRealMatrixToOjalgo(g);
        MatrixStore C = OjAlgoUtils.convertColumnRealVectorToOjalgo(correctedF);
        MatrixStore AI = OjAlgoUtils.convertRealMatrixToOjalgo(S);
        MatrixStore BI = OjAlgoUtils.convertColumnRealVectorToOjalgo(a);
        
        QuadraticSolver.Builder builder = new QuadraticSolver.Builder(Q, C).inequalities(AI, BI);
        
        QuadraticSolver solver = builder.build();
        
        solver.options.timeLimit = 250;
//        solver.options.iterationsLimit = 50;
        
        Result result = solver.solve();
        
        if (result.getState().isLessThan(State.FEASIBLE)) {
            System.out.println("Solução NÃO encontrada.");
        } else {
            System.out.println("Solução encontrada!!!");
        }
        
        System.out.println("ESTADO: " + result.getState());
        System.out.println("ITERAÇÕES: " + result.getIterationsCount());
        System.out.println("SOLUÇÃO: " + result.getSolution().doubleValue(0, 0));
        
        if (result.getState().isLessThan(State.FEASIBLE)) {
            return MathCommonsUtils.convertMatrixToColumnVector(MathCommonsUtils.zeros(g.getRowDimension(), 1));
//            return OjAlgoUtils.convertOjalgoToRealVector(result.getSolution());
        } else {
            return OjAlgoUtils.convertOjalgoToRealVector(result.getSolution());
        }
    }
    
}
